<?php

class Crc_Validate_UniqueEntity extends Zend_Validate_Abstract
{
	/**
	* Error constants
	*/
	const ERROR_RECORD_FOUND = 'recordFound';

	/**
	* @var array Message templates
	*/
	protected $_messageTemplates = array(
		self::ERROR_RECORD_FOUND => 'Duplicate \'%value%\'',
	);

	/**
	*
	* @var \Doctrine\ORM\EntityManager
	*/
	protected $_entityManager;

	/**
	*
	* @var Entity
	*/
	protected $_matchedEntity;

	/**
	*
	* @var string
	*/
	protected $_matchedEntityClass;

	/**
	*
	* @var string
	*/
	protected $_field;

	public function __construct(array $options = null)
	{
		Zend_Debug::dump($options);exit;
		if (isset($options['entityManager']) && $options['entityManager'] instanceof \Doctrine\ORM\EntityManager) {
			$this->_entityManager = $options['entityManager'];
		} else {
			$doctrine = Zend_Registry::get('doctrine');
            $this->_entityManager = $doctrine->getEntityManager();
		}

		if (isset($options['entity'])) {
			try {
				$entity = new $options['entity']();
				if ($entity instanceof \Crc\Entity\AbstractEntity) {
					$this->_matchedEntity = $entity;
				} else {
					throw new Zend_Validate_Exception('Entity must be instance of \Crc\Entity\AbstractEntity!');
				}
			} catch(\Exception $e) {
				throw new \Zend_Validate_Exception('Entity must be instance of \Crc\Entity\AbstractEntity!', 0, $e);
			}
		} else {
			throw new Zend_Validate_Exception('Entity must be instance of \Crc\Entity\AbstractEntity!');
		}

		if (isset($options['field']) && is_string($options['field'])) {
			$this->_field = $options['field'];
		} else {
			throw new Zend_Validate_Exception('Provided parameter $field must be a string!');
		}

		$metadata = $this->_entityManager
						 ->getMetadataFactory()
						 ->getMetadataFor(\get_class($this->_matchedEntity));
		$this->_matchedEntityClass = $metadata->reflClass->getName();
		try {
			if(!$metadata->getFieldMapping($this->_field)) {
				throw new \Zend_Validate_Exception('Matched entity does not contain field \'' . $this->_field . '\'!');
			}
		} catch(\Exception $e) {
			throw new \Zend_Validate_Exception('Matched entity does not contain field \'' . $this->_field . '\'!', 0, $e);
		}
	}

	public function isValid($value)
	{
		if(
			\is_object($value)
			&& $value instanceof \Crc\Entity\AbstractEntity
		) {
			if(!($value instanceof $this->_matchedEntityClass)) {
				throw new \Zend_Validate_Exception('Value to be validated must be an instance of \'' . $this->_matchedEntityClass . '\'!');
			}
			$value = $value[$this->_field];
		}
		$this->_setValue($value);
		if(
			$match = $this->_entityManager
						  ->getRepository($this->_matchedEntityClass)
						  ->findOneBy(array($this->_field => $value))
		) {
			Zend_Debug::dump($match);exit;
			if($match->getId() !== $this->_matchedEntity->getId()) {
				$this->_error(self::ERROR_RECORD_FOUND);
				return false;
			}
		}
		return true;
	}
}
